Le fichier de style est un fichier facultatif permettant de modifier le style de base de l'index via des balises spécifiques.
Chaque balise (identiques à celles de makeindex) permet de contrôler la mise en forme d'une partie de l'index. Par exemple :
heading_prefix "{\vspace{1.5cm}\huge{\textbf{"
heading_suffix "}}\hfill}\nopagebreak"
permettent de modifier l'aspect de l'en-tête d'un groupe de lettres.
L'ensemble des balises suivantes sont entièrement compatibles avec makeindex
preamble
postamble
headings_flag
heading_prefix
heading_suffix
symhead_positive
numhead_positive
group_skip
item_0
item_1
item_2
item_01
item_12
delim_0
delim_1
delim_2
delim_n
Ces balises sont spécifiques à HsIndex et n'existent pas avec makeindex.
headings_flag1
heading_prefix1
heading_suffix1
group_skip1
Pour simplifier l'utilisation du programme par un utilisateur lambda, les balises doivent pouvoir être lues dans n'importe quel ordre et être facultatives. Implémenter un tel parser pourrait s'avérer compliqué mais heureusement parsec contient des fonctions dédiées à cet usage.
Ces fonctions se trouvent dans le module Text.Parsec.Perm
de la bibliothèque.
permute
:
permet d'encapsuler un parser spécifique pour tester des permutations.
<$?>
:
Crée un parser de permutation en y ajoutant un parser standard facultatif.
<|?>
:
Ajoute un parser standard facultatif.
<$$>
:
Crée un parser de permutation en y ajoutant un parser standard obligatoire.
<||>
:
Ajoute un parser standard obligatoire.
Ici, ce sont les opérateurs permettant d'ajouter des parser facultatifs qui nous intéressent. Ces opérateurs prennent comme argument un doublet contenant une valeur par défaut et un parser permettant de rechercher cette valeur.
Pour pouvoir parser un fichier de style complet, on aura donc cette fonction :
parseStyleFile :: IndexStyle -> Parser IndexStyle
parseStyleFile sty = do
emptyLines
sty <- permute (IndexStyle
<$?> (idxPreamble sty , try $ parseStyleDef "preamble")
<|?> (idxPostamble sty , try $ parseStyleDef "postamble")
<|?> (idxHeadingFlag0 sty, try $ parseStyleDefHead "headings_flag")
...
...
<|?> (idxDelimn sty , try $ parseStyleDef "delim_n")
)
eof
return sty
Cette fonction prendra comme argument le style par défaut et retournera le nouveau style modifié, prenant en compte les modifications indiquées dans le fichier de style. Les fonctions idxPreamble sty
, idxPostamble sty
permettant de renseigner les valeurs par défaut et les fonctions parseStyleDef "preamble"
et parseStyleDefHead "headings_flag"
lancent des parser pour récupérer les balises dédiées.
parseStyleDef :: String -> Parser String
parseStyleDef str = do
string str
many1 (char ' ')
def <- between (char '"') (char '"') (many1 $ noneOf "\r\n\t\"")
many (char ' ')
endOfLineP
emptyLines
return (literalNewLine def)
On recherche le nom de la balise passée en argument avec string str
.
On saute un ou plusieurs espaces entre le nom de la balise et sa chaîne.
On récupère la chaîne contenue entre deux guillemets avec many1 $ noneOf "\r\n\t\""
.
On saute d'éventuels espaces.
On détecte la fin de ligne avec endOfLineP
.
On saute d'éventuelles lignes vides avec la définition de balise suivante.
Note: Si les guillemets n'étaient pas exclus dans la liste des caractères à rechercher le parser échouerait car il ne s'arrêterait pas à la fin de la définition de la balise.
La balise de titre doit être suivie d'un chiffre positif, négatif ou 0 pour indiquer si le titre doit être en majuscule, en minuscule, ou si aucun titre n'est à afficher:
parseStyleDefHead :: String -> Parser Heading
parseStyleDefHead str = do
string str
many1 (char ' ')
s <- option ' ' (char '-')
h <- many1 digit
many (char ' ')
endOfLineP
emptyLines
return (val2Heading (read (s:h)))
On recherche le nom de la balise passée en argument avec string str
.
On saute un ou plusieurs espaces entre le nom de la balise et le chiffre.
On récupère un potentiel signe avec la fonction option ' ' (char '-')
. Cette fonction tente d'appliquer et de récupérer le résultat du parser char '-'
. En cas d'échec, la valeur par défaut ' '
est retournée.
On saute d'éventuels espaces.
On détecte la fin de ligne avec endOfLineP
.
On saute d'éventuelles lignes vides avec la définition de balise suivante.
Et la fonction val2Heading
retourne le type Heading
associé à la valeur passée en argument.
val2Heading 0 = None
val2Heading n = if n > 0
then UpperCase
else LowerCase
Voilà pour l'analyseur syntaxique du fichier de style.